<?php

namespace app\common\library\wxpay;


class WxSign
{
    /**
     * 根据Url传递的参数，生成签名字符串
     * @param array $param
     * @param string $signType
     * @param $md5Key
     * @return string
     * @throws \Exception
     */
    public function getSign(array $param, $signType = 'MD5', $md5Key)
    {
        $values = $this->paraFilter($param);
        $values = $this->arraySort($values);
        $signStr = $this->createLinkstring($values);

        $signStr .= '&key=' . $md5Key;
        switch ($signType)
        {
            case 'MD5':
                $sign = md5($signStr);
                break;
            case 'HMAC-SHA256':
                $sign = hash_hmac('sha256', $signStr, $md5Key);
                break;
            default:
                $sign = '';
        }
        return strtoupper($sign);
    }

    /**
     * 移除空值的key
     * @param $para
     * @return array
     */
    public function paraFilter($para)
    {
        $paraFilter = array();
        foreach ($para as $key => &$val)
        {
            if ($val == "") {
                continue;

            } else {
                if (! is_array($para[$key])) {
                    $para[$key] = is_bool($para[$key]) ? $para[$key] : trim($para[$key]);
                }

                $paraFilter[$key] = $para[$key];
            }
        }
        return $paraFilter;
    }

    /**
     * @function 对输入的数组进行字典排序
     * @param array $param 需要排序的数组
     * @return array
     * @author helei
     */
    public function arraySort(array $param)
    {
        ksort($param);
        reset($param);
        return $param;
    }

    /**
     * @function 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param array $para 需要拼接的数组
     * @return string
     * @throws \Exception
     */
    public function createLinkString($para)
    {
        if (! is_array($para)) {
            throw new \Exception('必须传入数组参数');
        }

        reset($para);
        $arg  = "";
        foreach ($para as $key => &$val){
            if (is_array($val)) {
                continue;
            }

            $arg.=$key."=".urldecode($val)."&";
        }
        //去掉最后一个&字符
        $arg = substr($arg, 0, strlen($arg) - 1);
        $arg = stripslashes($arg);
//        var_dump($arg);exit();
//        //如果存在转义字符，那么去掉转义
//        if (get_magic_quotes_gpc()) {
//            $arg = stripslashes($arg);
//        }else{
//            $arg=$arg;
//        }

        return $arg;
    }
    /**
     * 输出xml字符
     *
     * @param array $values
     * @return string|bool
     * @author xiewg
     **/
    public function toXml($values)
    {
        if (!is_array($values) || count($values) <= 0) {
            return false;
        }

        $xml = "<xml>";
        foreach ($values as $key => $val) {
            if (is_numeric($val)) {
                $xml.="<".$key.">".$val."</".$key.">";
            } else {
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    /**
     * 将xml转为array
     *
     * @param string $xml
     * @return array|false
     * @author xiewg
     */
    public function toArray($xml)
    {
        if (!$xml) {
            return false;
        }

        // 检查xml是否合法
        $xml_parser = xml_parser_create();
        if (!xml_parse($xml_parser, $xml, true)) {
            xml_parser_free($xml_parser);
            return false;
        }

        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);

        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

        return $data;
    }


}
